<template>
    <div class="magnifier">
        <canvas ref="canvasDom" :class="{ grab: isGrab, canvas: true }"></canvas>
        <canvas ref="offCanvasDom" class="off-canvas"></canvas>
    </div>
</template>

<script setup lang="ts">
import { onMounted } from 'vue';
import { ref } from 'vue';


const canvasDom = ref<HTMLCanvasElement>(), offCanvasDom = ref<HTMLCanvasElement>();
let ctx: CanvasRenderingContext2D | null | undefined, offCtx: CanvasRenderingContext2D | null | undefined;
const isGrab = false;
let point = {}, scale = 2;
let image: HTMLImageElement;
const onMousedown = function (e: MouseEvent) {
    if (canvasDom.value) {
        point = { x: e.offsetX, y: e.offsetY };
        drawCanvasWithMagnifier(true, point)
        canvasDom.value.addEventListener('mouseup', onMouseup, { once: true })
        canvasDom.value.addEventListener('mouseleave', onMouseup, { once: true })
        canvasDom.value.addEventListener('mousemove', onMousemove)
    }
}

const onMouseup = function () {
    drawCanvasWithMagnifier(false)
    canvasDom.value?.removeEventListener('mousemove', onMousemove)
}

const onMousemove = function (e: MouseEvent) {
    point = { x: e.offsetX, y: e.offsetY };
    drawCanvasWithMagnifier(true, point)
}


onMounted(async () => {
    if (canvasDom.value) {
        ctx = canvasDom.value.getContext('2d');
        console.log(111111112, canvasDom)
        canvasDom.value.width = canvasDom.value.offsetWidth;
        canvasDom.value.height = canvasDom.value.offsetHeight;
        if (offCanvasDom.value) {
            offCtx = offCanvasDom.value.getContext('2d');
            offCanvasDom.value.width = canvasDom.value.width * 2;
            offCanvasDom.value.height = canvasDom.value.height * 2;
        }
        image = new Image();
        image.onload = function () {
            ctx?.drawImage(image, 0, 0, 250 * 1.5, 410 * 1.5)
            offCtx?.drawImage(image, 0, 0, 250 * 1.5 * 2, 410 * 1.5 * 2)
        }
        image.src = (await import('../images/zhigengniao.jpg')).default;

        canvasDom.value.addEventListener('mousedown', onMousedown);
    }
})

const drawCanvasWithMagnifier = (isShow: any, point?: any) => {
    ctx?.clearRect(0, 0, canvasDom.value?.width || 0, canvasDom.value?.height || 0)
    ctx?.drawImage(image, 0, 0, 250 * 1.5, 410 * 1.5)
    if (isShow) {
        drawMagnifier(point)
    }
}

const drawMagnifier = (point: { x: number; y: number; }) => {
    const mr = 100;
    const imageLG_cx = point.x * scale;
    const imageLG_cy = point.y * scale;

    const sx = imageLG_cx - mr;
    const sy = imageLG_cy - mr;

    const dx = point.x - mr;
    const dy = point.y - mr;

    if (ctx) {
        ctx.save();
        ctx.lineWidth = 10;
        ctx.strokeStyle = '#333'
        ctx.beginPath()
        ctx.arc(point.x, point.y, mr, 0, Math.PI * 2)
        ctx.stroke();
        ctx.closePath();
        ctx.clip();
        offCanvasDom.value && ctx.drawImage(offCanvasDom.value, sx, sy, 2 * mr, 2 * mr, dx, dy, 2 * mr, 2 * mr)

        ctx.restore();
    }
}

</script>

<style scoped lang="scss">
.magnifier {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    // height: 600px;

    .canvas {
        // margin: 5% auto;
        width: 80%;
        height: 80%;
        border: 1px solid #00ced1;
    }

    .off-canvas {
        display: none;
    }
}

.grab {
    cursor: grab;
}
</style>